﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using AdaptiveAgents.Distributions;
using ZedGraph;

namespace GameAnalyzer
{
    public partial class frmStepDistributionCreator : Form
    {
        private decimal _totalArea = 0;
        private List<AdaptiveAgents.Distributions.Point> _retFunction = null;

        public frmStepDistributionCreator()
        {
            InitializeComponent();
            _retFunction = new List<AdaptiveAgents.Distributions.Point>();
        }

        /// <summary>
        /// Creates new step distribution by calling the distribution dialog
        /// </summary>
        /// <returns>new instance of step distribution</returns>
        public static IDistribution createStepDistribution()
        {
            frmStepDistributionCreator frm = new frmStepDistributionCreator();
            if (frm.ShowDialog() == DialogResult.OK)
            {
                 return new Blocks(frm._retFunction);
            }
            return null;
        }

        private void frmStepDistributionCreator_Load(object sender, EventArgs e)
        {

        }

        private void drawGraph()
        {
            //Clear previous graph
            zgcDist.GraphPane.CurveList.Clear();

            //Create the distribution graph
            GraphPane myPane = zgcDist.GraphPane;

            // Set the title and axis labels
            myPane.Title.Text = "";
            myPane.XAxis.Title.Text = "";
            myPane.YAxis.Title.Text = "";

            //Create a pair list
            PointPairList list = new PointPairList();
            
            //Scan each item in function table

            //list.Add(0, 0);
            double x0, y0, x1, y1;
            x0 = y0 = x1 = y1 = 0;
            list.Add(0, 1);
            for (System.Collections.IEnumerator itr = lvFunction.Items.GetEnumerator(); itr.MoveNext(); )
            {
                ListViewItem current = (ListViewItem)itr.Current;
                x0 = double.Parse(current.SubItems[0].Text);
                y0 = double.Parse(current.SubItems[2].Text);
                
                x1 = double.Parse(current.SubItems[1].Text) + x0;
                y1 = y0;

                list.Add(x0, y0);
                list.Add(x1, y1);
                //list.Add(double.Parse(current.SubItems[0].Text), double.Parse(current.SubItems[1].Text));
            }

            list.Add(x1, 0);
            list.Add(1, 0);
            // Add a red curve with circle symbols
            LineItem curve = myPane.AddCurve("Step", list, Color.Red, SymbolType.None);
            curve.Line.Width = 1.5F;
            // Fill the area under the curve
            curve.Line.Fill = new Fill(Color.White, Color.FromArgb(60, 190, 50), 90F);
            // Fill the symbols with white to make them opaque
            curve.Symbol.Fill = new Fill(Color.White);
            curve.Symbol.Size = 5;

            // Set the curve type to forward steps
            curve.Line.StepType = StepType.ForwardStep;

            // Limit the X axis to max value of the X array
            curve.GetXAxis(myPane).Scale.MaxGrace = 0f;

            // Calculate the Axis Scale Ranges
            zgcDist.AxisChange();
        }

        private void btn_Click(object sender, EventArgs e)
        {
            if (((Button)sender).Tag.Equals("Add"))
            {
                //Create new line in table
                String[] values = new String[4];
                values[0] = nudX.Value.ToString();
                values[1] = nudLength.Value.ToString();
                values[2] = nudHeight.Value.ToString();
                values[3] = nudArea.Value.ToString();
                
                ListViewItem item = new ListViewItem(values);
                
                //Scan each existing line in table
                for(System.Collections.IEnumerator itr = lvFunction.Items.GetEnumerator(); itr.MoveNext();)
                {
                    //Check if already exists such line
                    ListViewItem current = (ListViewItem)itr.Current;
                    if (current.SubItems[0].Text.Equals(values[0]) && 
                        current.SubItems[1].Text.Equals(values[1]) &&
                        current.SubItems[2].Text.Equals(values[2]))
                        return;
                }

                _totalArea += nudArea.Value;

                /*if (_totalArea > 1)
                {
                    _totalArea -= nudArea.Value;
                    MessageBox.Show("Total area cannot be greater than 1.0", "Step Distribution Creator", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }*/

                if (nudX.Value + nudLength.Value > 1)
                {
                    MessageBox.Show("Total length cannot be greater than 1.0", "Step Distribution Creator", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }

                lvFunction.Items.Add(item);
                _retFunction.Add(new AdaptiveAgents.Distributions.Point((double)nudX.Value, (double)nudHeight.Value));
                
                lblTotalArea.Text = _totalArea.ToString();

                nudX.Value += nudLength.Value;

                //Check if distribution is valid
                //if (_totalArea == 1)
                //    btnDone.Enabled = true;
            }
            else if (((Button)sender).Tag.Equals("Clear"))
            {
                lvFunction.Items.Clear();
                nudX.Value = nudLength.Value = nudHeight.Value = nudArea.Value = 0;
                _totalArea = 0;
                btnDone.Enabled = false;
                _retFunction.Clear();
            }
            else if (((Button)sender).Tag.Equals("Done"))
            {
                //TODO - add to list the end of the last block
                _retFunction.Add(new AdaptiveAgents.Distributions.Point((double)nudX.Value, 0));
                return;
            }

            
            drawGraph();



            this.Refresh();
        }

        private void nud_ValueChanged(object sender, EventArgs e)
        {
            if (((NumericUpDown)sender).Tag.Equals("Length"))
            {
                nudArea.Value = nudHeight.Value * nudLength.Value; //Change area

                return;
            }

            if (((NumericUpDown)sender).Tag.Equals("Area"))
            {
                nudHeight.Value = nudArea.Value / nudLength.Value; //Change height

                return;
            }

            /*
            if (((NumericUpDown)sender).Tag.Equals("Height"))
            {
                nudArea.Value = nudHeight.Value * nudLength.Value; //Change area
                
                return;
            }*/
        }
    }
}
